; msgbox.asm
; Message box implementation

	.include "common.inc"
	.include "global.inc"
	.include "util.inc"
	.include "memory.inc"
	.include "petscii.inc"
	.include "text.inc"
	.include "window.inc"
	.include "wutil.inc"
	.include "screen.inc"

	.export initmsgbox
	.export message

	.segment "RODATA"

txtmsg:		.byte 7, $4D, $05, $13, $13, $01, $07, $05
txtwarn:	.byte 7, $57, $01, $12, $0E, $09, $0E, $07
txterr:		.byte 5, $45, $12, $12, $0F, $12
txtquest:	.byte 8, $51, $15, $05, $13, $14, $09, $0F, $0E 

txtlistlo:	.byte <txtmsg, <txtwarn, <txterr, <txtquest
txtlisthi:	.byte >txtmsg, >txtwarn, >txterr, >txtquest 	

	.segment "DATA"
	
	MAX_LINES = 8
	
h_message:	.byte 0 ; Message frame handle
w_message:	.byte 0 ; Message window handle
msgtype:	.byte 0 ; Message type
titlefont:	.byte 1 ; Title font
msgfont:	.byte 2 ; Message font
msgtext:	.word 0 ; Message text
textw:		.byte 0 ; Text width
texth:		.byte 0 ; Text height
lineh:		.byte 0 ; Line height
linecols:	.byte 0 ; max chars per line
emwidth:	.byte 0 ; em width
linecnt:	.byte 0	; number of lines
lineslen:	.res MAX_LINES	; line cols
linesofs:	.res MAX_LINES	; line offsets
textlen:	.byte 0	; length of text
actstart:	.byte 0 ; act line start
acty:		.byte 0 ; act Y for text boxes
curline:	.byte 0 ; current text line for text boxes
bufptr:		.word 0

	BORDER_X = 4
	BORDER_Y = 6
	DIST_Y = 4
	MIN_X = 80
	MIN_Y = 2*(BORDER_Y+8)

	.segment "BOOT"

initmsgbox:	lda #1
			ldx #1
			jsr malloc
			sta bufptr
			stx bufptr+1
			rts

	.segment "CODE"

message:	; A/X ... text (petscii), Y .. type (0 .. message, 1 .. warning, 2 .. error)
			sta msgtext
			stx msgtext+1
			sty msgtype
			jsr clclncols
			jsr convtext
			jsr clctxtdim
			; alloc frame
			lda textw
			clc
			adc #2*BORDER_X
			cmp #MIN_X
			bcs @dnx
			lda #MIN_X
@dnx:		tax
			and #$0F
			beq @dnx2
			txa
			and #$F0
			clc
			adc #$10
			tax
@dnx2:		lda texth
			clc
			adc #2*BORDER_Y+WIN_TITLE_HEIGHT
			cmp #MIN_Y
			bcs @dny
			lda #MIN_Y
@dny:		tay
			jsr frm_create
			sta h_message
			jsr frm_center
			ldy #FFLG_TEMP
			jsr frm_setflags
			; create window
			jsr frm_getwin
			sta w_message
			jsr win_realize
			lda #WSTYLE_BCKGND+WSTYLE_HASTITLE+WSTYLE_BORDER
			jsr win_setstyle
			lda titlefont			; lower case system font
			jsr win_setfont
			lda msgtype
			and #3
			tay
			lda txtlisthi, y
			tax
			lda txtlistlo, y
			jsr win_settext
			lda w_message
			jsr addclsbtn
			; create message text fields
			lda #BORDER_Y+WIN_TITLE_HEIGHT-DIST_Y
			sta acty		; setup y offset
			lda #0			; init curline := 0
			sta curline
@txtfldlp:	ldx curline		; check loop condition
			cpx linecnt
			bcs @drwwindow
			lda w_message	; create text field
			jsr win_create
			lda #0
			jsr win_setstyle
			ldx #BORDER_X
			lda acty
			clc
			adc #DIST_Y
			tay
			adc lineh
			sta acty
			jsr win_setpos
			ldx textw
			ldy lineh
			jsr win_setdim
			lda msgfont
			jsr win_setfont
			ldx curline		; setup text ptr
			lda linesofs, x
			clc
			adc bufptr
			sta reg2
			lda #0
			adc bufptr+1
			sta reg2+1
			lda lineslen, x
			ldy #0
			sta (reg2), y
			lda reg2
			ldx reg2+1
			jsr win_settext
			inc curline
			jmp @txtfldlp
			; draw window			
@drwwindow:	lda w_message
			jsr win_draw
			lda w_message
			jsr win_show			; to screen
			; done
			rts

clclncols:	lda msgfont
			jsr getemsize
			stx emwidth		; calc max line width
			sty lineh
			lda scr_dim_x
			sec
			sbc #2*BORDER_X
			jsr bdiv
			; X = max chars/line
			stx linecols
			rts

convtext:	; Convert text
			lda msgtext
			sta reg2
			ldx msgtext+1
			stx reg2+1
			ldy #0
			lda (reg2), y
			clc
			adc #1
			tay
			lda #0
			adc #0
			tax
			sty textlen
			tya
			lda bufptr
			sta reg1
			lda bufptr+1
			sta reg1+1
			ldx #0
			ldy #1
			sty actstart
@mcptext:	lda (reg2), y
			cmp #$0D		; CR
			bne @nocr
			jsr	addtext
			iny
			sty actstart
			bne @nxtln
@nocr:		jsr pet2scr
			sta (reg1), y
			iny
@nxtln:		cpy textlen
			bcc @mcptext
			jsr addtext
			stx linecnt
			rts

addtext:	cpx #MAX_LINES
			bcs @nomore
			tya				; get current position
			sec				; calc length
			sbc	actstart
			beq @nomore
			cmp linecols
			bcc @lenok
			lda linecols	; trunc to max len, TODO: line wrap
@lenok:		sta lineslen, x
			lda actstart
			sec
			sbc #1
			sta linesofs, x
			inx
@nomore:	rts

clctxtdim:	; get max text dimensions
			ldx #0
			lda lineslen, x
			sta textw
			lda lineh
			sta texth
@nextline:	inx
			cpx linecnt
			bcs @doneno
			lda texth
			clc
			adc #DIST_Y
			adc lineh
			sta texth
			lda lineslen, x
			cmp textw
			bcc @nextline
			sta textw
			bcs @nextline
@doneno:	lda textw
			asl			; hard-coded 4px-width font
			asl
			sta textw
			rts
